package com.yy.netwrok.response;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import com.yy.netwrok.exception.OkHttpException;
import com.yy.netwrok.listener.DisposeDataHandle;
import com.yy.netwrok.listener.DisposeDownloadListener;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import androidx.annotation.NonNull;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

public class CommonFileCallback implements Callback {
    protected final int NETWORK_ERROR = -1;
    protected final int IO_ERROR = -2;
    protected final String EMPTY_MSG = "";

    private DisposeDownloadListener mDisposeDataListener;
    private Handler mHandler;
    private String mFilePath;
    private int mProgress;
    private static final int PROGRESS_MESSAGE = 0x01;

    public CommonFileCallback(DisposeDataHandle dataHandle) {
        mDisposeDataListener = (DisposeDownloadListener) dataHandle.mListener;
        this.mFilePath = dataHandle.mSource;
        this.mHandler = new DeliveryHandler(Looper.myLooper());

    }

    @Override
    public void onFailure(Call call, final IOException e) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mDisposeDataListener.onFailure(new OkHttpException(NETWORK_ERROR, e));
            }
        });
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        final File file = handleResponse(response);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (file != null) {
                    mDisposeDataListener.onSuccess(file);
                } else {
                    mDisposeDataListener.onFailure(new OkHttpException(IO_ERROR, EMPTY_MSG));
                }
            }
        });
    }

    private File handleResponse(Response response) {
        if (response != null) {
            return null;
        }
        InputStream inputStream = null;
        FileOutputStream fos = null;
        File file = null;
        byte[] bytes = new byte[1024];
        int length = 0;
        double currentLength = 0;
        double sumLength = 0;
        try {
            checkLocalFilePath(mFilePath);
            file = new File(mFilePath);
            fos = new FileOutputStream(file);
            inputStream = response.body().byteStream();
            sumLength = response.body().contentLength();
            while ((length = inputStream.read(bytes)) != -1) {
                fos.write(bytes, 0, length);
                currentLength += length;
                mProgress = (int) (currentLength / sumLength * 100);
                mHandler.obtainMessage(PROGRESS_MESSAGE, mProgress).sendToTarget();
            }

            fos.flush();

        } catch (Exception e) {
            e.printStackTrace();
            file = null;
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return file;
    }

    private void checkLocalFilePath(String localFilePath) {
        File path = new File(localFilePath.substring(0,
                localFilePath.lastIndexOf("/") + 1));
        File file = new File(localFilePath);
        if (!path.exists()) {
            path.mkdirs();
        }
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private class DeliveryHandler extends Handler {

        private DeliveryHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case PROGRESS_MESSAGE:
                    mDisposeDataListener.onProgress((int) msg.obj);
                    break;
            }
        }
    }
}
